package transientTest.clone;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
 
/**
 * @author lcx
 *
 * 测试深复制方法：
 * 1. 利用字节码作为中转，totalClone方法
 * 2. 利用文件作为中转，totalCloneByFile方法
 * 两种方法均可，但是被克隆的类需实现java.io.Serializable
 * 否则会出现java.io.NotSerializableException:
 * 
 */
public class DeepCopyTest {

	public static void main(String[] args) throws FileNotFoundException {
		A a=new A(2);
		
		A b=(A) a.totalCloneByFile(a);
//		A b=(A) a.totalClone(a);
		
//		a.b.bstr="***";
//		b.val=6;
		System.out.println("a=="+a.val+"   "+a.getB().bstr);
		System.out.println("b=="+b.val+"   "+b.getB().bstr);
	}
	
	
}

class A implements Serializable
{
	public int val=1;
	public B b=new B();
	public A(int val)
	{
		this.val=val;
	}

	/**
	 * 使用深复制，通用性更强
	 * 深复制可以用ByteArray中转也可以用txt中转
	 * @param o
	 * @return
	 */
	public Object totalClone(Object o)
	{
		ByteArrayOutputStream baos=new ByteArrayOutputStream();
		try
		{
		ObjectOutputStream oos=new ObjectOutputStream(baos);
		oos.writeObject(o);
		ByteArrayInputStream bais=new ByteArrayInputStream(baos.toByteArray());
		ObjectInputStream ois=new ObjectInputStream(bais);
		return ois.readObject();
		}
		catch(IOException ex)
		{
			ex.printStackTrace();
		}
		catch(ClassNotFoundException ex)
		{
			ex.printStackTrace();
		}
		
		return null;
	}


	/**
	 * 使用深复制，通用性更强
	 * 深复制可以用ByteArray中转也可以用txt中转
	 * @param o
	 * @return
	 * @throws FileNotFoundException 
	 */
	public Object totalCloneByFile(Object o) throws FileNotFoundException
	{
		FileOutputStream baos=new FileOutputStream("a.txt");
		try
		{
		ObjectOutputStream oos=new ObjectOutputStream(baos);
		oos.writeObject(o);
		FileInputStream bais=new FileInputStream("a.txt");
		ObjectInputStream ois=new ObjectInputStream(bais);
		return ois.readObject();
		}
		catch(IOException ex)
		{
			ex.printStackTrace();
		}
		catch(ClassNotFoundException ex)
		{
			ex.printStackTrace();
		}
		
		return null;
	}
	
	public B getB()
	{
		return this.b;
	}
	public Object clone()
	{
		try {
			A o=(A)super.clone();
			o.b=(B) this.b.clone();
			return o;
		} catch (CloneNotSupportedException e) {
			e.printStackTrace();
		}
		return null;
	}

	class B implements Serializable
	{
		public String bstr="*";
		
		public Object clone()
		{
			try {
				return super.clone();
			} catch (CloneNotSupportedException e) {
				e.printStackTrace();
			}
			return null;
		}
	}
}
